<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script>
    //1. 利用 new Object() 创建对象
    var obj1 = new Object()

    //2. 利用对象字面量,json形式船舰对象
    var obj3 = {}

    //3. 利用构造函数创建对象
    function Star(name, age) {
      this.name = name
      this.age = age
      // this.sing = function (){
      //   console.log("唱歌...")
      // }
    }

    // Star.prototype.sing = function () {
    //   console.log("唱歌ing...")
    // }
    //
    // Star.prototype.movie = function () {
    //   console.log("拍戏ing...")
    // }
    Star.prototype = {
      //对象的形式给原型对象赋方法,需要手动将构造方法指向原来的构造函数
      constructor: Star,
      sing(){
        console.log("唱歌ing...")
      },
      movie(){
        console.log("拍戏ing...")
      }
    }
    var ldh = new Star("刘德华", 22);
    /**
     * 注意使用构造函数不需要return
     * 访问属性必须通过对象.
     */
    //静态成员,构造函数.属性, 调用静态属性,只能通过构造函数访问,不可以通过对象访问!
    Star.sex = '男'
    //问题.构造函数好用,但是存在浪费空间的问题,每一个对象都会在堆中存放相同函数,浪费大量内存,引入原型 prototype
    //构造函数通过原型分配的函数是所有对象所共享的
    //js规定,每一个构造函数都有一个prototype属性,指向另一个对象,注意之歌prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有
      var zxy = new Star("张学友", 22)
    console.log(ldh.sing === zxy.sing)
    console.dir(Star)
    //确认是由protptype这个对象
    //我们可以把那些不变的方法,直接定义在prototype对象上,这样所有的实例就可以共享这些方法

    /**
     * 重点:
     *  原型是一个对象,prototype称为原型对象
     *  原型的作用是:   共享方法  !
     *  一般情况下,公共属性定义放到构造函数里面,公共的方法放到原型对象身上!
     */

    //对象原型 __proto__
    //每一个对象都会有一个属性, __proto__ 指向的是构造函数的prototype原型对象,之所以我们的对象可以调用原型对象里方法,即使因为这个__proto__的存在
    console.log(ldh)
    //方法查找的规则,首先看ldh这个对象身上是否有sing方法,如果有就执行这个对象上的sing,如果没有就从__proto__也就是原型对象上找方法,并执行
    console.log(ldh.__proto__ === Star.prototype)
    //注意: __proto__对象原型的意义在于为对象的查找机制提供了一个方向,但它是非标准属性,实际的开发中不可以使用这个属性,他只是内部指向原型形的prototype

    //在对象原型 和 原型对象 里面都一个属性, constructor属性,constructor我们成为构造函数,因为他指向构造函数本身
    console.log(Star.prototype.constructor)
    console.log(ldh.__proto__.constructor)


  </script>
</head>
<body>

</body>
</html>